home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / asm_msc1.arc / PRINTER.ASM < prev    next >
Assembly Source File  |  1988-11-20  |  26KB  |  515 lines

  1. TITLE Printer
  2. PAGE 66,132
  3. ;* * * * * * * * * * * * * *   P R I N T E R   * * * * * * * * * * * * * * *  
  4. ;
  5. ;                             John C. Petrey
  6. ;                                (c) 1983
  7. ;
  8. ;
  9. ;
  10. ;
  11. CSEG    segment para public 'CODE'
  12.         org     100h    
  13. ;
  14. ;
  15. PRINTER proc    far
  16.         assume cs:cseg,ds:cseg,es:nothing
  17. ;
  18.         jmp     set_up
  19. ;
  20. ;Data Area
  21. ;
  22.         disk        db   00h                ;current default disk drive
  23.         bytes_left  db   00h                ;bytes of code left to read
  24.         sav_row     db   02h                ;start cursor at line 2 
  25.         kbd_input   db   ' '                ;save keyboard input
  26.         print_lit   db   'N'                ;flag to indicate if we were printing literal
  27.         option_nbr  db   '0'                ;option number printed on the screen
  28.         fcb         db   00h                ;1st byte of FCB (00h = default drive)
  29.         fcb2        db   'printer '         ;file name in FCB   
  30.         fcb3        db   'dat'              ;file extension in FCB
  31.         fcb4        db    25  dup(00h)      ;remainder of FCB 
  32.         dta         db   128  dup('d')      ;disk transfer area
  33.         eof         db   '$'                ;end of disk transfer area
  34.         codes       db   20  dup('c')       ;user codes
  35.         line1       db   'Printer (1.1) - Special Print Functions$' 
  36.         more        db   'Change another setting? $'      
  37.         nomatch     db   'Please choose an option listed above $'
  38.         quest       db   'Your Choice $'
  39.         option      db   'Option $'
  40.         done        db   ' done!$'
  41.         escape      db   'Esc -  Exit$'
  42.         dash        db   '   -  $'
  43.         no_file     db   'PRINTER.DAT file not found or error in file$'
  44. ;
  45. ;Setup stuff
  46.  set_up:
  47.         push    ds                      ;Set return segment address and ...
  48.         sub     ax,ax                   ;put zero on stack ...
  49.         push    ax                      ;so a RET returns us to starting address.   
  50.         push    cs                      ;Move work address into Data Segment ...
  51.         pop     ds                      ;because this is a COM file.
  52.                                         ;
  53. ;Save registers                         ;By saving register contents at program 
  54.         push    ax                      ;entry we insure exit will correctly
  55.         push    bx                      ;return to DOS.
  56.         push    cx
  57.         push    dx
  58.         sti                             ;enable interrupts
  59.                                         ;
  60. ;Set screen mode
  61.         mov     al,2                    ;80 x 25 B&W alpha
  62.         mov     ah,0                    ;BIOS interrupt 10 - set video mode
  63.         int     10h                     ;call BIOS to do it
  64.                                         ;
  65. ;Clear screen
  66.         mov     ah,6                    ;clear screen with scroll active page up
  67.         mov     al,0                    ;entire window
  68.         mov     cx,0                    ;ch,cl = row,column of upper left corner
  69.         mov     dh,24                   ;dh = row to scroll to
  70.         mov     dl,79                   ;dl = column to scroll to
  71.         mov     bh,7                    ;attribute to be used on blank line
  72.         int     10h                     ;Call BIOS to scroll 
  73.                                         ;
  74. ;Title
  75.         mov     dx,offset line1         ;get address of program title
  76.         call    print                   ;print it on the screen
  77.                                         ;
  78. ;Save current default disk drive
  79.         mov     ah,19h                  ;DOS function to get default drive
  80.         int     21h                     ;Call DOS to do it - returned in AL
  81.         mov     disk,al                 ;Save default disk returned in AL
  82.                                         ;
  83. ;Get drive on which PRINTER.DAT file is located
  84.         mov     si,80h                  ;point to command tail address
  85.         mov     dh,[si]                 ;get length of command tail
  86.         tail:
  87.         cmp     dh,00h                  ;Is their a command tail? or any bytes of tail left?
  88.         je      set_dta                 ;   no, go set DTA
  89.         dec     dh                      ;   yes, update bytes of tail left
  90.         inc     si                      ;        point to next byte in command tail
  91.         mov     dl,[si]                 ;        get contents of command tail       
  92.         cmp     dl,097                  ;Is drive spec upper case?
  93.         jb      upper                   ;   yes, now go fold to a value   
  94.         sub     dl,32                   ;   no, fold down to upper case
  95.         upper:
  96.         sub     dl,65                   ;fold to a value
  97.                                         ;
  98. ;Select disk drive
  99.         cmp     dl,5                    ;if value not valid (a - f) ...
  100.         ja      tail                    ;   get next command tail byte
  101.         cmp     dl,0                    ;if value not valid ...
  102.         jb      tail                    ;   get next command tail byte
  103.         mov     ah,0Eh                  ;DOS function to select disk
  104.         int     21h                     ;call DOS to do it
  105.                                         ;           
  106. ;Set Disk Transfer Address
  107.         set_dta:
  108.         mov     dx,offset dta           ;get address of Disk Transfer Area (DTA)
  109.         mov     ah,1Ah                  ;DOS function to set Disk Transfer Area (DTA)
  110.         int     21h                     ;call DOS to set DTA
  111.                                         
  112. ;Open File Control Block  
  113.         mov     dx,offset fcb           ;point to address of File Control Block (FCB)
  114.         mov     ah,0fh                  ;DOS function to open file control block
  115.         int     21h                     ;call DOS to open file control block
  116.                                         
  117.         mov     bp,00h                  ;initialize base pointer - used later
  118.                                         ;as offset into user codes
  119. ;
  120. ;Sequential read
  121.  read:
  122.         mov     dx,offset fcb           ;get address of file control block
  123.         mov     ah,14h                  ;DOS function to read a record
  124.         int     21h                     ;call DOS to do it.  AL returns 00 if successful.
  125.         cmp     al,00h                  ;Was read successful?
  126.         je      success                 ;  Yes, continue with program
  127.         cmp     al,03                   ;Was partial record read?
  128.         je      success                 ;  Yes, continue with program
  129.         file_not_found:
  130.         mov     dx,offset no_file       ;  No, get address of error message
  131.         call    cursor                  ;      print error message
  132.         jmp     exit                    ;      exit
  133.         success:
  134.                                         ;
  135.         mov     SI,00h                  ;initialize SI to zero - will use SI as offset
  136.                                         ;within DTA (byte were currently working with)
  137.                                         ;
  138.         cmp     dta[si],'&'             ;Is this the end of the users file?
  139.         jne     not_end                 ;  No, still more to read
  140.         jmp     cont                    ;  Yes, we're done reading users file
  141.         not_end:                        ;
  142.                                         ;
  143.         cmp     bytes_left,0            ;Were we reading codes when we reached end of DTA?
  144.         je      not_reading             ;  No
  145.         jmp     read_code               ;  Yes, go finsih reading codes
  146.         not_reading:
  147.                                         ;                                           
  148.         cmp     dta[si],'$'             ;Did we just finish printing a literal when we
  149.                                         ;reached the end of the DTA?
  150.         je      end_of_literal          ;  Yes, now read codes
  151.                                         ;
  152.         cmp     print_lit,'Y'           ;Were we printing the literal when we reached the end of the DTA?
  153.         je      finish_print            ;  Yes, go finish printing the literal      
  154. ;
  155. ;Parse DTA -  Print user literals & save user codes in opt0 - opt9
  156. ;               User's file must be in the following format:
  157. ;                 1)  Literal of unspecified lengthed ending with "$"
  158. ;                     followed by exactly 2 control codes of which
  159. ;                     each must be 3 digits in decimal notation.
  160. ;
  161. ;                 2)  Last digit of last code in file should be followed
  162. ;                     by an ampersand "&"           
  163. ;
  164. ;               Reister uses: 
  165. ;                 SI = on entry is address of start of DTA, subsequently
  166. ;                      it is the offset into the DTA (points to byte we
  167. ;                      are currently looking at.
  168. ;                 BP = offset within CODES
  169. ;
  170. ;
  171. print_literal:
  172.         inc     sav_row                 ;will print literal on next row down
  173.         mov     dh,sav_row              ;set new cursor position
  174.         call    loc                     ;call locate cursor procedure to do it
  175.         mov     dl,option_nbr           ;get number of option (0 to 9)
  176.         mov     ah,2                    ;DOS function to print character in DL
  177.         int     21h                     ;let DOS print option number
  178.         inc     option_nbr              ;increment option nbr for next time
  179.         ;
  180.         mov     dx,offset dash          ;get address of dash literal
  181.         call    print                   ;print dash literal
  182.         ;
  183. finish_print:
  184.         mov     dx,offset dta           ;get address of start of DTA
  185.         add     dx,si                   ;add SI to DX to get address of literal
  186.                                         ;
  187.         mov     di,dx                   ;set DI to address of literal
  188.         cmp     byte ptr [di],0Dh       ;Are we looking at a carriage return?
  189.         jne     not_CR                  ;  No, look at next byte
  190.         inc     dx                      ;  Yes, point to next byte
  191.         not_CR:
  192.         mov     di,dx
  193.         cmp     byte ptr [di],0Ah       ;Are we looking at a Line Feed?
  194.         jne     not_LF                  ;  No, we can now print the literal
  195.         inc     dx                      ;  Yes, point to next byte
  196.         not_LF:
  197.                                         ;
  198.         mov     print_lit,'Y'           ;Set flag to indicate we were printing literal
  199.         mov     ah,9                    ;DOS function to print literal pointed to in DX
  200.         int     21h                     ;call DOS to print literal
  201.         ;
  202.     next_byte:                          ;This loop updates DX to point
  203.                                         ;to the location in the DTA where
  204.                                         ;the codes begin.
  205.                                         ;
  206.         inc     si                      ;Point to next byte in DTA.
  207.                                         ;
  208.         cmp     si,128d                 ;If we are at the end of the DTA,
  209.         jae     read                    ;go get next sector of user's file.
  210.                                         ;
  211.         cmp     si,127d                 ;Are we at next to last byte in the DTA?
  212.         jne     not_127                 ;  No, continue
  213.         cmp     dta[si],'$'             ;  Yes, and is this a end of literal mark?
  214.         jne     not_127                 ;    No, continue
  215.         mov     bytes_left,6            ;    Yes, will read 6 bytes of code
  216.         mov     print_lit,'N'           ;         turn off printing literal flag
  217.         jmp     read                    ;         and get next sector
  218.         not_127:
  219.                                         ;
  220.         cmp     dta[si],'$'             ;If DX pointing to end of literal,
  221.         je      end_of_literal          ;go read the codes following the literal.
  222.                                         ;
  223.         jmp     next_byte               ;Otherwise, get next byte in DTA.
  224.                                         ;
  225.                                         ;
  226.     end_of_literal:                                                      
  227.         mov     print_lit,'N'           ;Set flag to indicate we are not printing the literal
  228.         mov     bytes_left,6            ;Will read 6 bytes of code.
  229.         inc     si                      ;Point to first byte of code.
  230.         cmp     si,128d                 ;Are we are pointing to end of the DTA?
  231.         jbe     first_byte              ;  No, read first byte of code.       
  232.         jmp     read                    ;  Yes, go read next sector of users code.
  233.                                         ;
  234.     read_code:
  235.         cmp     bytes_left,6            ;If we reached the end of the DTA 
  236.         je      first_byte              ;reading the codes this jump table
  237.         cmp     bytes_left,5            ;will return us to the place where
  238.         je      five_left               ;we left off.  The value in CL is
  239.         cmp     bytes_left,4            ;the number of bytes we have left 
  240.         je      four_left               ;to read.
  241.         cmp     bytes_left,3
  242.         je      three_left
  243.         cmp     bytes_left,2
  244.         je      two_left   
  245.         cmp     bytes_left,1
  246.         je      last_byte_jmp           ;This jump arround stuff is required only
  247.         jmp     exit                    ;becasue it's to far for a conditional jump
  248.         last_byte_jmp:  jmp last_byte
  249.                                         ;
  250.     first_byte:
  251.         call    byte1
  252.         mov     dl,100d                 ;1st byte of code is 100's place
  253.         mov     bl,0                    ;initialize sum to zero - will use BL to
  254.                                         ;accumulate hex value of users code
  255.         call    byte2   
  256.         cmp     si,128                  ;Are we at end of DTA?
  257.         jb      five_left               ;  No, continue.
  258.         jmp     read                    ;  Yes, get next sector
  259.                                         ;
  260.     five_left:
  261.         call    byte1
  262.         mov     dl,10d                  ;2nd byte of user's code is 10's place
  263.         call    byte2
  264.         cmp     si,128                  ;Are we at end of DTA?
  265.         jb      four_left               ;  No, continue.
  266.         jmp     read                    ;  Yes, get next sector.    
  267.                                         ;   
  268.     four_left:
  269.         call    byte1
  270.         add     bl,al                   ;add one's place to sum in BL
  271.         call    byte3
  272.         cmp     si,128                  ;Are we at end of DTA?
  273.         jb      three_left              ;No, continue.
  274.         jmp     read                    ;Yes, get next sector.
  275.                                         ;
  276.     three_left:
  277.         call    byte1
  278.         mov     dl,100d                 ;1st byte is 100's place
  279.         mov     bl,0                    ;initialize sum to zero - will use BL to 
  280.                                         ;accumulate hex value of users code
  281.         call    byte2
  282.         cmp     si,128                  ;Are we at end of DTA?
  283.         jb      two_left                ;  No, continue.
  284.         jmp     read                    ;  Yes, get next sector
  285.                                         ;
  286.     two_left:
  287.         call    byte1
  288.         mov     dl,10d                  ;2nd byte is 10's place
  289.         call    byte2
  290.         cmp     si,128                  ;Are we at end of DTA?
  291.         jb      last_byte               ;  No, continue.
  292.         jmp     read                    ;  Yes, get next sector.
  293.                                         ;
  294.     last_byte:
  295.         call    byte1
  296.         add     bl,al                   ;add one's place to sum in BL
  297.         call    byte3
  298.         cmp     si,128                  ;Are we at end of DTA?
  299.         jb      end_codes               ;  No, continue.
  300.         jmp     read                    ;  Yes, get next sector.
  301.                                         ;
  302.     end_codes:
  303.         cmp     dta[si],'&'             ;Is next byte and end of file marker?
  304.         je      cont                    ;  Yes, we're done.
  305.         cmp     bp,20d                  ;Have we written all 10 codes (20 bytes)
  306.         je      cont                    ;  Yes, we're done.
  307.         jmp     print_literal           ;  No, print the next literal
  308. ;
  309. ;
  310. cont:
  311.         inc     sav_row                 ;set cursor to next row
  312.         mov     dh,sav_row              ;set new cursor position
  313.         call    loc                     ;call locate procedure to set cursor at next row
  314.         mov     dx,offset escape        ;get address of "ESC - Exit" literal
  315.         call    print                   ;print escape literal 
  316.                                         ;
  317.         mov     sav_row,10h             ;set cursor to be at line 16 (message line) 
  318.         call    msgs                    ;locate cursor at messages line
  319.         mov     dx,offset quest         ;print question "your choise"
  320.         call    print  
  321. ;
  322. ;
  323. kboard: call    kbd
  324.         mov     [kbd_input],al          ;save user's input in kbd_input
  325.         cmp     al,1Bh                  ;Check to see if input was escape key
  326.         je      escp                    ;  Yes, go print message & exit
  327.                                         ;
  328.         cmp     al,'0'                  ;Check to see if input was less than zero
  329.         jl      none                    ;  Yes, print error message
  330.                                         ;
  331.         cmp     al,option_nbr           ;Check to see if input was greater than nbr options
  332.         jae     none                    ;  Yes, print error message
  333.                                         ;
  334.         sub     al,30h                  ;fold user's ASCII character to a quantity
  335.         mov     dl,2                    ;get offset into codes by multiplying users
  336.         mul     dl                      ;input in AL times 2 (2 bytes per option)
  337.         mov     di,ax                   ;move result to DI (offset into CODES pointing 
  338.                                         ;to option user wants to execute                                ;
  339.                                         ;
  340. ;First byte of code
  341.         mov     dl,offset codes[di]     ;get users code into DL
  342.         cmp     dl,0                    ;Is code zero?
  343.         je      next_code               ;  Yes, get next code
  344.                                         ;
  345.         call    sendit                  ;send code in DL to printer
  346.                                         ;
  347.         inc     di                      ;point to next code
  348.                                         ;
  349. ;Second byte of code
  350. next_code:
  351.         mov     dl,offset codes[di]     ;get users code into DL
  352.         cmp     dl,0                    ;Is code zero?
  353.         je      finished                ;  Yes, we're done - go print Done!
  354.                                         ;
  355.         call    sendit                  ;send code in DL to printer
  356.                                         ;
  357. finished:
  358.         mov     dx,offset option        ;get address of Option literal
  359.         call    cursor                  ;call procedure to print literal
  360.         mov     dl,[kbd_input]          ;move user's keyboard input to DL
  361.         mov     ah,2                    ;DOS function to print character in DL
  362.         int     21h                     ;call DOS to print users keyboard input
  363.         mov     dx,offset done          ;get address of done! literal
  364.         call    print                   ;call print procedure to print the literal
  365.         jmp     again                   ;go ask user if he wants to play again
  366.                                         ;
  367. none:
  368.         call    msgs                    ;clear the message line
  369.         mov     dx,offset nomatch       ;get address of nomatch literal
  370.         call    print                   ;call print procedure to print literal
  371.         jmp     kboard                  ;go wait for user input
  372. ;
  373. escp:
  374.         call    msgs                    ;blank-out message line
  375.         mov     dh,23                   ;position cursor at ...
  376.         call    loc                     ;line 23        
  377.         jmp     exit                    ;We're DONE!!!!
  378. ;
  379. again:  call    msgs                    ;blank-out message line line
  380.         mov     dx,offset more          ;print more literal
  381.         call    print                   ;call print procedure to print more literal
  382.         jmp     kboard                  ;go wait for user input
  383. ;
  384. exit:
  385.         mov     dl,disk                 ;get original default disk drive
  386.         mov     ah,0Eh                  ;DOS function to set default disk drive
  387.         int     21h                     ;Call DOS to do it
  388.                                         ;
  389.         pop     dx                      ;restore registers so the
  390.         pop     cx                      ;exit to DOS works OK.
  391.         pop     bx
  392.         pop     ax
  393.         int 20h                         ;Program terminate & return to DOS
  394. ;
  395. PRINTER endp
  396. ;
  397. ;
  398. ;
  399. BYTE1   proc
  400. ;   
  401.         mov     al,dta[si]              ;get 1st byte of user's code     
  402.         sub     al,30h                  ;convert to hex quantity (from ASCII)
  403.         ret
  404. BYTE1   endp
  405. ;
  406. ;
  407. BYTE2   proc
  408. ;
  409.         mul     dl                      ;Multiply times value in AL - result in AX
  410.         add     bl,al                   ;Add low byte of result to BL
  411.         inc     si                      ;point to next code in DTA
  412.         dec     bytes_left              ;first byte is done
  413.         ret
  414. BYTE2   endp
  415. ;
  416. ;
  417. BYTE3   proc
  418. ;
  419.         mov     codes[bp],bl            ;put user's code (converted to hex quantity) into CODE
  420.         inc     bp                      ;point to next byte in CODE
  421.         inc     si                      ;point to next byte in DTA
  422.         dec     bytes_left              ;now there are three bytes left
  423.         ret
  424. BYTE3   endp
  425. ;
  426. ;
  427. KBD     proc                            ;This proc reads input from the keyboard
  428. ;                                   
  429.         mov     ah,1                    ;  DOS function to read char from keyboard
  430.         int     21h                     ;  call DOS to do it
  431.         ret
  432. KBD     endp
  433. ;
  434. ;
  435. ;
  436. CURSOR  proc                            ;This proc restores the cursor to
  437.                                         ;the position last saved, moves the
  438.                                         ;cursor to down one line and lastly
  439.                                         ;saves the new cursor position
  440.                                         ;
  441.         push    dx                      ;save address of display message
  442.                                         ;
  443.         mov     dh,sav_row              ;get row last saved
  444.         inc     dh                      ;add one to row
  445.         cmp     dh,22                   ;test to see if row is at 22 yet
  446.         jb      no                      ;  no, continue
  447.         mov     dh,21                   ;  yes, set row to 21
  448.     no:
  449.         mov     sav_row,dh              ;save current row
  450.         call    loc                     ;set cursor at new location
  451.         pop     dx                      ;restore address of display message
  452.         call    print                   ;call print procedure to print message
  453.         ret                             ;return
  454. CURSOR  endp                        
  455. ;
  456. ;
  457. ;
  458. PGE     proc                            ;This proc gets the active display
  459.         mov     ah,15                   ;page returning it in bh
  460.         int     10H
  461.         ret
  462. PGE     endp
  463. ;
  464. ;
  465. ;
  466. LOC     proc                            ;This proc sets the cursor at the
  467.                                         ;row number set in dh
  468. ;
  469.         call    pge                     ;get active page number
  470.         mov     dl,0                    ;column 0
  471.         mov     ah,2
  472.         int     10H
  473.         ret
  474. LOC     endp
  475. ;
  476. ;
  477. ;
  478. PRINT   proc                            ;This proc sends the data pointed
  479.                                         ;to by register DX to the screen 
  480.                                         ;for display
  481.                                         ;
  482.         mov     ah,9
  483.         int     21h
  484.         ret
  485. PRINT   endp                                    
  486. ;
  487. ;   
  488. SENDIT  proc                            ;This proc sends the contents of
  489.                                         ;register DL to the printer
  490.                                         ;
  491.         mov     ah,5
  492.         int     21H
  493.         ret
  494. SENDIT  endp                    
  495. ;
  496. ;
  497. MSGS    proc                            ;This proc locates the cursor at
  498.                                         ;the message line (line 15)
  499.                                         ;
  500.         mov     dh,15                   ;locate cursor at line 15
  501.         call    loc                     ;call locate procedure
  502.         mov     cx,75                   ;75 times we will ...
  503.         mov     dl,' '                  ;print spaces
  504.         print_space:
  505.         mov     ah,2                    ;DOS function to print character in DL
  506.         int     21h                     ;call DOS to print the space
  507.         loop    print_space             ;If CX is not zero, jump to print_space         
  508.         mov     dh,15                   ;locate cursor at line 15
  509.         call    loc                     ;call locate procedure
  510.         ret
  511. MSGS    endp
  512. ;
  513. CSEG    ends
  514.         end     PRINTERooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo